package com.topcheer.common.datasource.aspect;

import com.topcheer.common.datasource.annotation.DynamicSource;
import com.topcheer.common.datasource.dynamic.DataSourceKeyBuilder;
import com.topcheer.common.datasource.exception.NoDataSourceKeyException;
import com.topcheer.common.datasource.holder.SimpleDataSourceInfoHolder;
import com.topcheer.common.datasource.vo.SimpleDataSourceInfo;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;

/**
 * @ClassName: DynamicDataSourceAspect
 * @Author: Lix
 * @Version: 1.0
 * @Date: 2019/12/26 15:48
 * @Description: TODO
 **/
@Aspect
@Configuration
public class DynamicDataSourceAspect {

    @Autowired(required = false)
    private DataSourceKeyBuilder dataSourceKeyBuilder;

    @Pointcut("@annotation(com.topcheer.common.datasource.annotation.DynamicSource)")
    public void dynamicDataSource(){

    }


    @Before("dynamicDataSource()")
    private void interceptor(JoinPoint joinPoint) throws Throwable {
        Object target = joinPoint.getTarget();
        String methodName = joinPoint.getSignature().getName();
        Class[] parameterTypes = ((MethodSignature) joinPoint.getSignature())
                .getMethod().getParameterTypes();
        Method method = target.getClass().getMethod(methodName, parameterTypes);
        if(method != null) {
            if (method.isAnnotationPresent(DynamicSource.class)) {
                checkDataSourceKeyBuilder();
                DynamicSource aktSource = method.getAnnotation(DynamicSource.class);
                String dataSourceKey = this.dataSourceKeyBuilder.builder(aktSource.value());
                if(!StringUtils.isEmpty(dataSourceKey)){
                    SimpleDataSourceInfoHolder.set(new SimpleDataSourceInfo(dataSourceKey, aktSource.value()));
                } else {
                    throw NoDataSourceKeyException.newException("DataSourceKeyBuilder生成的数据源key为空！！！");
                }
            }
        }
    }

    /**
     * 验证DataSourceKeyBuilder是否存在
     */
    private void checkDataSourceKeyBuilder(){
        if(dataSourceKeyBuilder == null){
            throw NoDataSourceKeyException.newException("当前未配置DataSourceKeyBuilder！！！");
        }
    }

    @After("dynamicDataSource()")
    private void remove(){
        SimpleDataSourceInfoHolder.remove();
    }
}
